/*
 ------------------------------------------------------------------------------
	sdlmedia - a test program for a media search library, including test UI.

	Copyright (C) 2011 Pierre Veber
	
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software Foundation,
	Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
------------------------------------------------------------------------------
*/

#pragma once
#include "mad/mad.h"
#include "SDL/SDL.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_Image.h"

#define IMAGE_JPEG	(int)0
#define IMAGE_PNG	(int)1

struct MediaInfo_t
{
	Uint16* pszArtist;
	Uint16* pszAlbum;
	Uint16* pszTrack;
	Uint16* pszYear;
	Uint16* pszTrackNum;
	Uint16* pszMsLength;
};

/* SDL custom events */
#define EV_MEDIA_LIB_FOLDERS_READY	(int)0x00000001
#define EV_MEDIA_LIB_TAGS_READY		(int)0x00000002

/* UI events */
#define UI_SHOW						(int)0x00000001

typedef int
	(*HandleSDLEvent)(struct View_t*, SDL_Event*);
typedef int
	(*HandleUIMessage)(struct View_t*, int, void*, long);

struct View_t
{
	HandleSDLEvent	fpHandleEvent;
	HandleUIMessage	fpHandleUIMessage;
};

/* audio engine data and functions */
#ifdef WIN32
typedef struct {
	HWAVEOUT	hWaveOut;
	HANDLE		hFreeBlock;
	WAVEHDR*	pHdr;
	LPSTR		pWaveData;
	DWORD		dwInitVolume;
	DWORD		dwAppVolume;
} AudioDevice_t;
#else
typedef struct {
	snd_pcm_t*	pHandle;
} AudioDevice_t;
#endif

int waveInit(
			AudioDevice_t* pAudio
			);

int waveWriteIn(
			AudioDevice_t* pAudio,
			const void* pBuffer,
			unsigned int frames
			);

void waveReset(
			AudioDevice_t* pAudio
			   );

void waveClose(
			AudioDevice_t* pAudio
			);

void waveMute(
			AudioDevice_t* pAudio
			);

void waveUnmute(
			AudioDevice_t* pAudio
			);

void waveSetVolume(
			AudioDevice_t* pAudio,
			WORD wVolume
			);

/* decoding data and functions */
typedef struct {
	FILE*			fp;
	char*			szFilePath;
	mad_decoder		decoder;
	AudioDevice_t	audio;
	SDL_Thread*		tDecodeThread;
	int				status;
	int				msg;
} DecodeData_t;

#define DECODE_STATUS_NONE		0
#define DECODE_STATUS_DECODING	1
#define DECODE_STATUS_FINISHED	2
#define DECODE_STATUS_PAUSED	3

#define DECODE_MSG_NONE		0
#define DECODE_MSG_STOP		1
#define DECODE_MSG_SEEK		2
#define DECODE_MSG_PAUSE	3
#define DECODE_MSG_RESUME	4

void send_message(DecodeData_t* pData, int msg);
int get_message(DecodeData_t* pData);
DecodeData_t* madDecode(AudioDevice_t* pAudio, const char* pszFile);
int madStop(DecodeData_t* pDecodeThreadData);
void madSeek(DecodeData_t* pDecodeThreadData);
void madPause(DecodeData_t* pDecodeThreadData);
void madResume(DecodeData_t* pDecodeThreadData);

typedef int
	(*MediaGetInfo)(FastHeap_t*, const char*, MediaInfo_t*);
typedef  SDL_Surface*
	(*MediaGetCover)(const char*);
typedef DecodeData_t*
	(*MediaDecode)(AudioDevice_t*, const char*);
typedef int
	(*MediaStop)(DecodeData_t*);
typedef void
	(*MediaSeek)(DecodeData_t*);
typedef void
	(*MediaPause)(DecodeData_t*);
typedef void
	(*MediaResume)(DecodeData_t*);

struct MediaDecoder_t
{
	char szName[128];
	char szSupportedExtensions[128];

	MediaGetInfo fpMediaGetInfo;
	MediaGetCover fpMediaGetCover;
	MediaDecode fpMediaDecode;
	MediaStop fpMediaStop;
	MediaSeek fpMediaSeek;
	MediaPause fpMediaPause;
	MediaResume fpMediaResume;
};

extern MediaDecoder_t Decoders[];
extern AudioDevice_t* pAudio;

extern SDL_Surface* pScreen;
extern View_t* pCurrentView;

extern char* pszFileToPlay;

/*
 ------------------------------------------------------------------------------
	Global UI Specs
------------------------------------------------------------------------------
*/

extern int _gi_AppWidth;
extern int _gi_AppHeight;
